/**
 * Copyright (c) 2025 myons Inc. All rights reserved.
 */
package cn.zmwh.common.core.utils;

import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.servlet.support.RequestContextUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Locale;

/**
 * 国际化工具类 (Spring集成版)
 * 功能：
 * 1. 自动与LocaleContextHolder集成
 * 2. 支持多级语言回退
 * 3. 内置防御性编程
 * 4. 提供快捷API
 * @describe: 、
 * @author: dmzmwh 、
 * @time: 2025-07-18 10:57 、
 */
public final class I18nUtils {

    private static MessageSource messageSource;

    // 私有构造防止实例化
    private I18nUtils() {}

    /**
     * 初始化工具类（需在Spring启动后调用）
     */
    public static void init(@NonNull MessageSource source) {
        Assert.notNull(source, "MessageSource must not be null");
        messageSource = source;
    }

    /* ------------------------ 核心方法 ------------------------ */

    /**
     * 获取当前语言环境
     */
    public static Locale currentLocale() {
        Locale locale = LocaleContextHolder.getLocale();
        if (locale == null) {
            locale = Locale.US;
        }
        return locale;
    }

    /**
     * 获取文本（自动使用当前Locale）
     * @param code 消息键
     * @return 国际化文本，若key不存在返回key本身
     */
    public static String get(@NonNull String code) {
        return get(code, null, code, currentLocale());
    }

    /**
     * 获取文本（带参数）
     * @param code 消息键
     * @param args 动态参数
     * @return 国际化文本，若key不存在返回key本身
     */
    public static String get(@NonNull String code, @Nullable Object... args) {
        return get(code, args, code, currentLocale());
    }

    /**
     * 获取文本（带默认值）
     * @param code 消息键
     * @param defaultMsg 默认文本
     * @return 国际化文本，若key不存在返回defaultMsg
     */
    public static String getWithDefault(@NonNull String code, @NonNull String defaultMsg) {
        if (messageSource == null) {
            return defaultMsg;
        }
        return get(code, null, defaultMsg, currentLocale());
    }

    /**
     * 强制使用指定Locale获取文本
     * @param code 消息键
     * @param locale 目标语言环境
     * @return 国际化文本
     */
    public static String getWithLocale(@NonNull String code, @NonNull Locale locale) {
        return get(code, null, code, locale);
    }

    /* ------------------------ 底层方法 ------------------------ */

    /**
     * 完整参数获取方法
     * @param code 消息键
     * @param args 动态参数
     * @param defaultMsg 默认文本
     * @param locale 语言环境
     * @return 格式化后的文本
     */
    public static String get(
            @NonNull String code,
            @Nullable Object[] args,
            @Nullable String defaultMsg,
            @NonNull Locale locale) {
        checkInitialized();
        try {
            return messageSource.getMessage(code, args, defaultMsg, locale);
        } catch (NoSuchMessageException e) {
            return defaultMsg != null ? defaultMsg : code;
        }
    }

    /* ------------------------ 私有方法 ------------------------ */

    private static void checkInitialized() {
        if (messageSource == null) {
            throw new IllegalStateException("I18nUtils not initialized. Call I18nUtils.init() first.");
        }
    }
}